#include <bits/stdc++.h>

#define in read()
#define fi first
#define se second
#define pb push_back
#define rep(i, x, y) for(int i = (x); i <= (y); i++) 
#define per(i, x, y) for(int i = (x); i >= (y); i--)

using namespace std;

using ll = long long;
using db = double;
using pii = pair < int , int >;
using vec = vector < int >;
using veg = vector < pii >;

int read() {
	int x = 0; bool f = 0; char ch = getchar(); while(!isdigit(ch)) f |= ch == '-', ch = getchar(); 
	while(isdigit(ch)) x = x * 10 + (ch ^ 48), ch = getchar(); return f ? -x : x;
}

const int N = 2e5 + 10;

int n, a[N], b[N], c[N], d[N];
multiset < int > s[N];

namespace vpot {
	int b[N << 1], cnt;
	inline void ins(int x) { b[++cnt] = x; }
	inline void build() { sort(b + 1, b + cnt + 1); cnt = unique(b + 1, b + cnt + 1) - b - 1; }
	inline int query(int x) { return lower_bound(b + 1, b + cnt + 1, x) - b; }
}

namespace seg {
	int s[N << 3], mn[N << 3];
	void pu(int x) { s[x] = s[x << 1] + s[x << 1 | 1]; mn[x] = min(mn[x << 1], s[x << 1] + mn[x << 1 | 1]); }
	void upd(int pos, int v, int o = 1, int l = 1, int r = vpot :: cnt) {
		if(l == r) return s[o] += v, mn[o] = min(s[o], 0), void(); int mid = l + r >> 1; 
		if(pos <= mid) upd(pos, v, o << 1, l, mid); else upd(pos, v, o << 1 | 1, mid + 1, r); pu(o);
	}
	bool query() { return mn[1] >= 0; }
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("1.in", "r", stdin);
#endif
	n = in; rep(i, 1, n) a[i] = in, b[i] = in, vpot :: ins(b[i]); rep(i, 1, n) c[i] = in, d[i] = in, vpot :: ins(d[i]);
	vpot :: build(); rep(i, 1, n) b[i] = vpot :: query(b[i]), d[i] = vpot :: query(d[i]);
	rep(i, 1, n) seg :: upd(b[i], 1), seg :: upd(d[i], -1), s[a[i]].insert(b[i]);
	assert(seg :: query());
	int ans = n;
	per(i, n, 1) {
		auto it = s[c[i]].upper_bound(d[i]);
		if(it != s[c[i]].begin()) {
			it--; int t = *it;
			seg :: upd(t, -1); seg :: upd(d[i], 1);
			if(seg :: query()) { s[c[i]].erase(it); ans--; }
			else seg :: upd(t, 1), seg :: upd(d[i], -1);
		}
	}
	printf("%d\n", ans);
	return 0;
}
